﻿using DongFangGuoKai.WCSPlatform.WebApi.Extensions;
using DongFangGuoKai.WCSPlatform.WebApi.ExternalSystem.WMSConmmon;
using DongFangGuoKai.WCSPlatform.WebApi.Utils.UtilModel;
using DongFangGuoKai.WCSPlatform.WebApi.Utils.WebSocketCommon;
using DongFangGuoKai.WMSPlatform.Commn.ExtendModule;
using S7.Net;
using System.Text.RegularExpressions;

namespace DongFangGuoKai.WCSPlatform.WebApi.Utils
{
    /// <summary>
    /// Plc任务
    /// </summary>
    public partial class PlcTaskManager
    {
        private readonly Plc plc;
        private readonly PlcDBAddress plcDBAddress;
        private readonly WMSHttpClient wmsHttpClient;
        private readonly ILogger<PlcTaskManager> logger;
        private readonly int taskTimeOut;
        private readonly WebSocketConnectManager socketManager;



        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="plcDBAddress"></param>
        /// <param name="wmsHttpClient">WMSHttp服务</param>
        /// <param name="logger"></param>
        /// <param name="taskTimeOut">任务超时处理时间</param>
        /// <param name="socketManager">webSocket管理类</param>
        public PlcTaskManager
        (
            Plc plc,
            PlcDBAddress plcDBAddress,
            WMSHttpClient wmsHttpClient,
            ILogger<PlcTaskManager> logger,
            int taskTimeOut,
            WebSocketConnectManager socketManager
        )
        {
            this.plc = plc;
            this.plcDBAddress = plcDBAddress;
            this.wmsHttpClient = wmsHttpClient;
            this.logger = logger;
            this.taskTimeOut = taskTimeOut;
            this.socketManager = socketManager;
        }
        /// <summary>
        /// 箱子号规则
        /// </summary>
        private static string pattern = @"^[A-Za-z]\d{5}$";
        /// <summary>
        /// 处理超时的任务
        /// </summary>
        /// <param name="task">要处理的Task</param>
        /// <param name="cts">token</param>
        /// <param name="logStr">需要记录的log</param>
        /// <param name="taskCode">清除的taskCode</param>
        /// <param name="func"></param>
        private void HandleTimeoutTask(Task task, CancellationTokenSource cts, string logStr, ushort taskCode, Action<ushort> func)
        {
            // 使用 Task.WaitAny 和 Task.Delay 来实现超时退出 使用时开启一个任务运行
            if (Task.WaitAny(new Task[] { task }, TimeSpan.FromSeconds(taskTimeOut)) < 0)
            {
                if (cts.Token.IsCancellationRequested == false)// 超时取消没有被取消的任务
                {
                    cts.Cancel();
                    func.Invoke(taskCode);
                    logger.LogError(logStr);
                }
            }
        }

        #region 出库
        /// <summary>
        /// 出库窗户口中的对应任务
        /// </summary>
        private static Dictionary<ushort, List<TaskPallet>> outWinCodeTaskPalletDic = new Dictionary<ushort, List<TaskPallet>>()
        {
            { 95,new List<TaskPallet>() },{ 94,new List<TaskPallet>()},
            { 93,new List<TaskPallet>() },{ 92,new List<TaskPallet>()},
            { 91,new List<TaskPallet>() },{ 90,new List<TaskPallet>()},
        };
        /// <summary>
        /// 获取全部出库任务
        /// </summary>
        /// <returns></returns>
        public Dictionary<ushort, List<TaskPallet>> GetOutTaskDic() => outWinCodeTaskPalletDic;
        /// <summary>
        /// 清除出库任务
        /// </summary>
        /// <param name="taskCode">为空则全部清除</param>
        /// <returns></returns>
        public bool DelOutTaskDic(ushort? taskCode)
        {
            try
            {
                if (taskCode == null)
                {
                    outWinCodeTaskPalletDic = new Dictionary<ushort, List<TaskPallet>>()
                    {
                        { 95,new List<TaskPallet>() },{ 94,new List<TaskPallet>()},
                        { 93,new List<TaskPallet>() },{ 92,new List<TaskPallet>()},
                        { 91,new List<TaskPallet>() },{ 90,new List<TaskPallet>()},
                    };
                    return true;
                }
                else
                {
                    foreach (var item in outWinCodeTaskPalletDic)
                    {
                        var task = item.Value.FirstOrDefault(s => s.taskCode == taskCode);
                        if (task != null)
                        {
                            item.Value.Remove(task);
                        }
                    }

                    return true;
                }

            }
            catch (Exception) { throw; }

        }

        /// <summary>
        ///上一个出库箱子号
        /// </summary>
        private static string lastOutPalletCode = "\0\0\0\0\0\0";
        /// <summary>
        /// 出库分拨窗口
        /// </summary>
        public async void OutDoWork()
        {
            try
            {
                var palletList = new HashSet<string>();//现有的所有箱子号
                foreach (var item in outWinCodeTaskPalletDic)
                {
                    foreach (var citem in item.Value)
                    {
                        palletList.Add(citem.palletCode);
                    }
                }

                string? palletCode = plc.ReadString(plcDBAddress.DBNumber, plcDBAddress.OutPalletCode).HexToStr(); //箱子号
                if (palletCode != lastOutPalletCode
                    && Regex.IsMatch(palletCode, pattern)
                    && palletList.Contains(palletCode) == false)//读到箱子号和上一次相同则说明没有读到箱子
                {
                    var wmsRes = wmsHttpClient.GetNumber(palletCode, out string httpLog);//请求WMS获得窗口号
                    if (wmsRes.Code == 500)
                    {
                        logger.LogError(httpLog);
                        return;
                    }
                    if (wmsRes.Data.WinCode == 0)
                    {
                        logger.LogError("wms返回的窗口号为0");
                        return;
                    }
                    var dbAdress = DataTool.GetWinCodeDbAddress(wmsRes.Data.WinCode, plcDBAddress);//获取窗口号对应的任务地址
                    if (string.IsNullOrEmpty(dbAdress))//如果没有找到对应数据库地址说明WMS的窗口号错误
                    {
                        logger.LogError($"没有对应窗口号,WMS返回的窗口号{wmsRes.Data.WinCode}");
                        return;
                    }
                    var taskCode = DataTool.GetTaskCode();//生成一个任务号
                    //必须先写入任务号后写入目标站
                    var taskCodeWriteRes = await plc.WriteIsAsync(plcDBAddress.OutTaskCode, taskCode);
                    var winCodeWriteRes = await plc.WriteIsAsync(plcDBAddress.WinCode, wmsRes.Data.WinCode);//窗口号
                    if (taskCodeWriteRes == false || winCodeWriteRes == false)
                    {
                        logger.LogError($"写入失败,[taskCode{taskCode};winCode{wmsRes.Data.WinCode}]");
                        return;
                    }
                    lastOutPalletCode = palletCode;//必须放在验证写入成功之后
                    if (outWinCodeTaskPalletDic.TryGetValue(wmsRes.Data.WinCode, out var taskPalletList))//绑定任务号和箱子号
                    {
                        taskPalletList.Add(new TaskPallet(taskCode, palletCode, wmsRes.Data.OrderSn, wmsRes.Data.OutBoundNo));
                    }
                    //通知数字孪生
                    var twIn = new DigitalTwin(palletCode, 1, 2).ToJson();
                    var twInMsg = string.Empty;
                    try
                    {
                        await socketManager.SendMessageToAllClients(twIn);
                        twInMsg = $"通知数字孪生:[{twIn}]";
                    }
                    catch (Exception ex)
                    {
                        logger.LogInformation($"通知数字孪生失败,内容:[{twIn}],错误信息:[{ex.Message}]", ex);
                    }
                    //通过令牌令控制任务
                    var cts = new CancellationTokenSource();
                    var task = Task.Run(async () =>
                    {
                        try
                        {
                            await ReadOutTask(dbAdress, wmsRes.Data.WinCode, taskCode, cts);
                        }
                        catch (Exception)
                        {

                            throw;
                        }
                    }, cts.Token); //一个箱子开启一个任务来跟踪 不要使用await来等到任务完成,这样会阻塞代码
                    _ = Task.Run(() =>                   
                        HandleTimeoutTask(task, cts, $"手动出库任务超时自动退出,[taskCode:{taskCode},箱号:{palletCode},task状态:{task.Status}]", taskCode, s => DelOutTaskDic(taskCode))
                    );
                    logger.LogInformation($"出库任务[taskCode:{taskCode};窗口号:{wmsRes.Data.WinCode};箱子号:{palletCode}];{httpLog};{twInMsg}");
                }
            }
            catch (Exception) { throw; }
        }
        /// <summary>
        /// 手动出库
        /// </summary>
        /// <param name="palletCode"></param>
        /// <param name="winCode"></param>
        /// <returns></returns>
        public async Task<(bool success, string errorMsg)> ManualOutDoWork(string palletCode, ushort winCode)
        {
            string errorMsg = string.Empty;
            if (palletCode == lastOutPalletCode) return (false, "不可和上一个箱号重复");
            try
            {
                if (palletCode != lastOutPalletCode)
                {
                    var dbAdress = DataTool.GetWinCodeDbAddress(winCode, plcDBAddress);//获取窗口号对应的任务地址
                    if (string.IsNullOrEmpty(dbAdress))//如果没有找到对应数据库地址说明WMS的窗口号错误
                    {
                        logger.LogError($"没有对应的窗口号");
                        errorMsg = "没有对应的窗口号";
                        return (false, errorMsg);
                    }

                    var taskCode = DataTool.GetTaskCode();//生成一个任务号
                    var taskCodeWriteRes = await plc.WriteIsAsync(plcDBAddress.OutTaskCode, taskCode);//写入任务号
                    var winCodeWriteRes = await plc.WriteIsAsync(plcDBAddress.WinCode, winCode);//窗口号
                    if (taskCodeWriteRes == false || winCodeWriteRes == false)
                    {
                        errorMsg = "写入Plc失败，请重试";
                        return (false, errorMsg);
                    }
                    lastOutPalletCode = palletCode;//必须放在写入任务成功之后
                    if (outWinCodeTaskPalletDic.TryGetValue(winCode, out var taskPalletList))//绑定任务号和箱子号和单号
                        taskPalletList.Add(new TaskPallet(taskCode, palletCode, string.Empty, string.Empty));
                    //通知数字孪生
                    var twIn = new DigitalTwin(palletCode,1, 2).ToJson();
                    var twInMsg = string.Empty;
                    try
                    {
                        await socketManager.SendMessageToAllClients(twIn);
                        twInMsg = $"通知数字孪生:[{twIn}]";
                    }
                    catch (Exception ex)
                    {
                        logger.LogInformation($"通知数字孪生失败,内容:[{twIn}],错误信息:[{ex.Message}]", ex);
                    }
                    var cts = new CancellationTokenSource();
                    var task = Task.Run(async () =>
                    {
                        try
                        {
                            await ReadOutTask(dbAdress, winCode, taskCode, cts);
                        }
                        catch (Exception) { throw; }
                    }, cts.Token); //每个箱子开启一个任务去监听,不要使用awite去等待任务会造成代码的堵塞

                    _ = Task.Run(
                        () => HandleTimeoutTask(task, cts, $"手动出库任务超时自动退出,[taskCode:{taskCode},箱号:{palletCode}]", taskCode, s => DelOutTaskDic(taskCode))
                    );
                    logger.LogInformation($"手动出库任务[taskCode:{taskCode};窗口号:{winCode};箱子号:{palletCode}];{twInMsg}");
                }
                return (true, errorMsg);
            }
            catch (Exception) { throw; }
        }

        /// <summary>
        /// 开始读取相应的窗口号看看是否箱子被取走
        /// </summary>
        /// <param name="dbAddress">窗口地址</param>
        /// <param name="winCode">窗口号</param>
        /// <param name="taskCode">任务号</param>
        /// <returns></returns>
        public async Task ReadOutTask(string dbAddress, ushort winCode, ushort taskCode, CancellationTokenSource cts)
        {
            try
            {
                while (cts.Token.IsCancellationRequested == false)
                {
                    try
                    {
                        var dbVal = (ushort)plc.Read(dbAddress);//读取对应的窗口的值
                        if (plc.IsConnected && dbVal != 0 && dbVal == taskCode)//说明箱子已到达
                        {
                            //读取对应窗口号中的所有任务
                            var tryRes = outWinCodeTaskPalletDic.TryGetValue(winCode, out var taskPalletList);
                            if (tryRes == false || taskPalletList == null || taskPalletList.Count() <= 0)
                            {
                                logger.LogError($"(ReadOutTask)WCS中窗口:{winCode}的任务列表为空");
                                cts.Cancel();//任务完成标记任务取消
                                break;
                            }
                            var taskPallet = taskPalletList.FirstOrDefault(s => s.taskCode == dbVal);//找到已到达的箱子
                            if (taskPallet == null)
                            {
                                logger.LogError($"(ReadOutTask)在WCS中未找到任务{dbVal}");
                                cts.Cancel();//任务完成标记任务取消
                                break;
                            }
                            //拿箱子号去找到对应的单号
                            var orderSnByPallet = taskPalletList.FirstOrDefault(s => s.palletCode == taskPallet.palletCode);
                            var customerHttpLog = string.Empty;
                            var outBoundHttpLog = string.Empty;
                            var twInMsg = string.Empty;
                            try
                            {
                                var customerRes = wmsHttpClient.NoticeOutCustomer(new NoticeOutCustomerReq()
                                {
                                    OrderSn = taskPallet.orderSn,
                                    BarCode = taskPallet.palletCode
                                }, out customerHttpLog);
                                var boundRes = wmsHttpClient.NoticeOutBound(new NoticeOutBoundReq()
                                {
                                    OrderSn = taskPallet.orderSn,
                                    BarCode = taskPallet.palletCode,
                                    OutBoundNo = taskPallet.outBoundNo,
                                }, out outBoundHttpLog);
                                var twIn = new DigitalTwin(taskPallet.palletCode, 2, 2).ToJson();
                                try
                                {
                                    await socketManager.SendMessageToAllClients(twIn);
                                    twInMsg = $"通知数字孪生:[{twIn}]";
                                }
                                catch (Exception ex)
                                {
                                    logger.LogError($"通知数字孪生失败,内容:[{twIn}],错误信息:[{ex.Message}]",ex);
                                }
                            }
                            catch (Exception ex)
                            {
                                logger.LogError($"(ReadOutTask)通知WMS箱子到位接口异常:{ex.Message}");
                            }
                            

                            string logStr = $"窗口{winCode}的箱子{taskPallet.palletCode}已到位";
                            taskPalletList.Remove(taskPallet);
                            logger.LogInformation($"{logStr},窗口{winCode}剩余任务列表:{taskPalletList.ToJson()},{customerHttpLog},{outBoundHttpLog},{twInMsg}");

                            cts.Cancel();//任务完成标记任务取消
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"出库任务异常(ReadOutTask):{ex.Message}");
                    }
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }
            }
            catch (Exception) { throw; }

        }
        /// <summary>
        /// 输送线中间故障 手动送到目标窗口号
        /// </summary>
        /// <returns></returns>
        public bool ManualOutEnd(string palletCode,ushort winCode,out string errMsg)
        {
            try
            {
                errMsg=string.Empty;
                //读取对应窗口号中的所有任务
                var tryRes = outWinCodeTaskPalletDic.TryGetValue(winCode, out var taskPalletList);
                if (tryRes == false || taskPalletList == null || taskPalletList.Count() <= 0)
                {
                    logger.LogError($"(ReadOutTask)WCS中窗口:{winCode}的任务列表为空");
                    errMsg = $"窗口号错误,此窗口中没有任何任务";
                    return false;
                }
                var taskPallet = taskPalletList.FirstOrDefault(s => s.palletCode == palletCode);//找到已到达的箱子
                if (taskPallet == null)
                {
                    logger.LogError($"(ReadOutTask)在WCS中未找到任务{palletCode}");
                    errMsg = $"系统故障,WCS中没有箱号{palletCode}的任务";
                    return false;
                }
                //拿箱子号去找到对应的单号
                string customerHttpLog = string.Empty;
                string outBoundHttpLog = string.Empty;
               
                try
                {
                    var customerRes = wmsHttpClient.NoticeOutCustomer(new NoticeOutCustomerReq()
                    {
                        OrderSn = taskPallet.orderSn,
                        BarCode = taskPallet.palletCode
                    }, out customerHttpLog);
                    if (customerRes.Code == 500) errMsg = "通知叫号机取号异常,"+customerRes.Msg;
                    var boundRes = wmsHttpClient.NoticeOutBound(new NoticeOutBoundReq()
                    {
                        OrderSn = taskPallet.orderSn,
                        BarCode = taskPallet.palletCode,
                        OutBoundNo = taskPallet.outBoundNo,
                    }, out outBoundHttpLog);
                    var twIn = new DigitalTwin(taskPallet.palletCode, 2, 2).ToJson();
                    var twInMsg = string.Empty;
                    try
                    {
                        socketManager.SendMessageToAllClients(twIn).Wait();
                        twInMsg = $"通知数字孪生:[{twIn}]";
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"通知数字孪生失败,内容:[{twIn}],错误信息:[{ex.Message}]", ex);
                    }
                    if (customerRes.Code == 500) errMsg +="通知WMS出库完成异常,"+customerRes.Msg;
                }
                catch (Exception ex)
                {
                    logger.LogError($"(ReadOutTask)通知WMS箱子到位接口异常:{ex.Message}");
                }
               
                string logStr = $"输送线异常,手动到位箱子[箱号:{winCode},箱号:{taskPallet.palletCode}]";
                taskPalletList.Remove(taskPallet);
                logger.LogInformation($"{logStr},窗口{winCode}剩余任务列表:{taskPalletList.ToJson()},{customerHttpLog},{outBoundHttpLog}");
                return true;

            }
            catch (Exception ex)
            {
                logger.LogError($"出库任务异常(ReadOutTask):{ex.Message}");
                errMsg = "系统异常,请重试";
                return false;
            }
        }
        #endregion

        #region 入库
        /// <summary>
        /// 入库任务 key：TaskCode  val:托盘条码
        /// </summary>
        public static Dictionary<ushort, string> inTaskPalletDic = new Dictionary<ushort, string>();
        /// <summary>
        /// 获取全部入库任务
        /// </summary>
        /// <returns></returns>
        public Dictionary<ushort, string> GetInTaskDic() => inTaskPalletDic;
        /// <summary>
        /// 清除入库任务
        /// </summary>
        /// <param name="taskCode">为空则全部清除</param>
        /// <returns></returns>
        public bool DelInTaskDic(ushort? taskCode)
        {
            try
            {
                if (taskCode == null)
                {
                    inTaskPalletDic = new Dictionary<ushort, string>();
                    return true;
                }
                else
                {
                    if (inTaskPalletDic.TryGetValue(taskCode.Value, out var palletCode))
                    {
                        inTaskPalletDic.Remove(taskCode.Value);
                    }
                    else throw new Exception($"{taskCode}任务不存在");
                    if (inTaskPalletDic.ContainsKey(taskCode.Value) == false)
                    {
                        return true;
                    }

                    return false;
                }

            }
            catch (Exception) { throw; }

        }
        /// <summary>
        /// 上一个入库箱子号
        /// </summary>
        private static string lastInPallCode = "\0\0\0\0\0\0";
        /// <summary>
        /// 入库任务
        /// </summary>
        public async void InDoWork()
        {
            try
            {
                string? palletCode = plc.ReadString(plcDBAddress.DBNumber, plcDBAddress.InPalletCode).HexToStr(); //入库箱子号
                if (palletCode != lastInPallCode
                    && Regex.IsMatch(palletCode, pattern)
                    && inTaskPalletDic.Values.Contains(palletCode) == false)
                {
                    var taskCode = DataTool.GetTaskCode();
                    //必须先写入任务号后写入目标站
                    var taskCodeWriteRes = await plc.WriteIsAsync(plcDBAddress.InTaskCode, taskCode);
                    var taskEndWriteRes = await plc.WriteIsAsync(plcDBAddress.InTaskEnd, (ushort)20);//入库目标站
                    if (taskCodeWriteRes == false || taskEndWriteRes == false) return;
                    lastInPallCode = palletCode;//必须放在写入任务成功之后
                    inTaskPalletDic.Add(taskCode, palletCode);
                    logger.LogInformation($"入库任务 [taskCode:{taskCode},箱子号:{palletCode}]");
                    var cts = new CancellationTokenSource();
                    var task = Task.Run(async () =>
                    {
                        try
                        {
                            await ReadInTask(taskCode, cts);
                        }
                        catch (Exception)
                        {

                            throw;
                        }
                    }, cts.Token);//一个箱子开启一个任务来跟踪 不需要使用await来等到任务完成,这样会阻塞代码 会读取不到下一个箱子
                    _ = Task.Run(() =>
                    {
                        HandleTimeoutTask(task, cts, $"手动入库任务超时自动退出,[taskCode:{taskCode},箱号:{palletCode}]", taskCode, s => DelInTaskDic(taskCode));
                    });
                }
            }
            catch (Exception) { throw; }

        }
        /// <summary>
        /// 手动下任务测试使用
        /// </summary>
        public async Task<(bool success, string errorMsg)> ManualInDoWork(string palletCode)
        {
            try
            {
                if (palletCode == lastInPallCode) return (false, "不可和上一个箱号重复");
                if (palletCode != lastInPallCode)
                {
                    var taskCode = DataTool.GetTaskCode();
                    var taskCodeWriteRes = await plc.WriteIsAsync(plcDBAddress.InTaskCode, taskCode);
                    var taskEndWriteRes = await plc.WriteIsAsync(plcDBAddress.InTaskEnd, (ushort)20);//入库目标站
                    if (taskCodeWriteRes == false || taskEndWriteRes == false) return (false, "写入Plc失败,请重试");
                    lastInPallCode = palletCode;//必须放在写入任务成功之后
                    inTaskPalletDic.Add(taskCode, palletCode);
                    var cts = new CancellationTokenSource();
                    var task = Task.Run(async () =>
                    {
                        try
                        {
                            await ReadInTask(taskCode, cts);
                        }
                        catch (Exception){throw;}
                    }, cts.Token);//一个箱子开启一个任务来跟踪 不需要使用await来等到任务完成,这样会阻塞代码 会读取不到下一个箱子
                    var twIn = new DigitalTwin(palletCode, 1, 2).ToJson();
                    var twInMsg = string.Empty;
                    try
                    {
                        await socketManager.SendMessageToAllClients(twIn);
                        twInMsg = $"通知数字孪生:[{twIn}]";
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"通知数字孪生失败,内容:[{twIn}],错误信息:[{ex.Message}]", ex);
                    }
                    _ = Task.Run(() =>
                    {
                        HandleTimeoutTask(task, cts, $"手动入库任务超时自动退出,[taskCode:{taskCode},箱号:{palletCode}]", taskCode, s => DelInTaskDic(taskCode));
                    });
                    logger.LogInformation($"手动入库任务 [任务号:" + taskCode + ",箱号:" + palletCode + "];"+ twInMsg);
                }
                return (true, "成功");
            }
            catch (Exception) { throw; }

        }
        /// <summary>
        /// 监听入库任务
        /// </summary>
        /// <param name="taskCode">入库任务号</param>
        /// <returns></returns>
        public async Task ReadInTask(ushort taskCode, CancellationTokenSource cts)
        {
            try
            {
                while (cts.Token.IsCancellationRequested == false)
                {
                    try
                    {
                        var inTaskCodeVal = (ushort)plc.Read(plcDBAddress.InTerminalTask);
                        if (inTaskCodeVal == taskCode)
                        {
                            if (inTaskPalletDic.TryGetValue(inTaskCodeVal, out var palletCode))
                            {
                                cts.Cancel();
                                var wmsRes = wmsHttpClient.NoticeInBox(palletCode, out var httpLog);
                                if (wmsRes.Code is 500)
                                {
                                    logger.LogError(httpLog + $";WMS返回异常,请手动处理箱子{palletCode}");
                                    inTaskPalletDic.Remove(inTaskCodeVal);//清除已完成的任务
                                    break;
                                }
                                var twIn = new DigitalTwin(palletCode, 2, 1).ToJson();
                                var twInMsg = string.Empty;
                                try
                                {
                                    await socketManager.SendMessageToAllClients(twIn);
                                    twInMsg = $"通知数字孪生:[{twIn}]";
                                }
                                catch (Exception ex)
                                {
                                    logger.LogError($"通知数字孪生失败,内容:[{twIn}],错误信息:[{ex.Message}]", ex);
                                }
                                inTaskPalletDic.Remove(inTaskCodeVal);//清除已完成的任务
                                logger.LogInformation($"入库箱子号{palletCode}已到位,剩余入库任务列表:{inTaskPalletDic.ToJson()},{httpLog},{twInMsg}");

                                break;
                            }
                        }
                        await Task.Delay(1000);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"入库任务异常(ReadInTask):{ex.Message}");
                        return;
                    }

                    await Task.Delay(1000);
                }
            }
            catch (Exception) { throw; }
        }
        #endregion 出库
       
    }
}
